﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using ShenNius.Repository;
using ShenNius.Repository.Extensions;
using ShenNius.Shop.API.Domain.Entity;
using ShenNius.Shop.API.Dtos.Input;
using ShenNius.Sys.API.Controllers;
using ShenNius.Sys.API.Domain.Entity;
using ShenNius.Sys.API.Domain.Repository;
using ShenNius.Sys.API.Domain.ValueObjects.Enum;
using ShenNius.Sys.API.Dtos.Common;
using ShenNius.Sys.API.Infrastructure;
using ShenNius.Sys.API.Infrastructure.Attributes;
using ShenNius.Sys.API.Infrastructure.Common;
using ShenNius.Sys.API.Infrastructure.Configs;
using SqlSugar;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ShenNius.Shop.API.Controllers
{
    /// <summary>
    /// 商品分类控制器
    /// </summary>
    [Route("api/shop/[controller]/[action]")]
    [MultiTenant]
    [ApiController]
    public class CategoryController : ControllerBase
    {
        private readonly IBaseRepository<Category> _repository;
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;
        private readonly ICurrentUserContext _currentUserContex;
        private readonly IRecycleRepository _recycleRepository;

        public CategoryController(IBaseRepository<Category> repository, ISqlSugarClient ISqlSugarClient, IMapper mapper, ICurrentUserContext currentUserContex, IRecycleRepository recycleRepository)
        {
            _repository = repository;
            _db = ISqlSugarClient;
            _mapper = mapper;
            _currentUserContex = currentUserContex;
            _recycleRepository = recycleRepository;
        }
        /// <summary>
        /// 分类列表
        /// </summary>
        /// <returns></returns>
        [HttpGet, Authority]
        public async Task<ApiResult> GetListPages([FromQuery] KeyListTenantQuery query)
        {
            var res = await _db.Queryable<Category>().Where(d => !d.IsDeleted && d.TenantId == query.TenantId)
                .WhereIF(!string.IsNullOrEmpty(query.Key), c => c.Name.Contains(query.Key))
                .OrderBy(c => c.CreateTime, OrderByType.Desc).ToPageAsync(query.Page, 2000);
            var tenants = await _db.Queryable<Tenant>().Where(d => d.IsDeleted == false).ToListAsync();
            foreach (var item in res.Items)
            {
                item.TenantName = tenants.Where(d => d.Id == item.TenantId).Select(d => d.Name).FirstOrDefault();
            }
            var result = new List<Category>();
            if (!string.IsNullOrEmpty(query.Key))
            {
                var menuModel = await _repository.GetModelAsync(m => m.Name.Contains(query.Key) && !m.IsDeleted);
                WebHelper.ChildNode(res.Items, result, menuModel.ParentId);
            }
            else
            {
                WebHelper.ChildNode(res.Items, result, 0);
            }
            if (result?.Count > 0)
            {
                foreach (var item in result)
                {
                    var name = WebHelper.LevelName(item.Name, item.Layer);
                    item.ChangeName(name);
                }
                return new ApiResult(data: new { count = res.TotalItems, items = result });
            }
            else
            {
                return new ApiResult(data: new { count = res.TotalItems, items = res.Items });
            }
        }
        [HttpPost, Authority]
        public async Task<ApiResult> Add([FromBody] CategoryInput input)
        {
            var CategoryModel = await _repository.GetModelAsync(d => d.Name.Equals(input.Name) && !d.IsDeleted);
            if (CategoryModel?.Id > 0)
            {
                return new ApiResult("已经存在类目名称了");
            }
            var category = _mapper.Map<Category>(input);
            var categoryId = await _repository.AddAsync(category);
            category.ChangeId(categoryId);
            var result = await WebHelper.DealTreeData(input.ParentId, categoryId, async () =>
           await _repository.GetModelAsync(d => d.Id == input.ParentId));
            category.ChangeParentList(result.Item1, result.Item2);
            var i = await _repository.UpdateAsync(category);
            return new ApiResult(i);
        }
        [HttpPut, Authority]
        public async Task<ApiResult> Modify([FromBody] CategoryModifyInput input)
        {
            var categoryModel = await _repository.GetModelAsync(d => d.Name.Equals(input.Name) && d.Id != input.Id && !d.IsDeleted);
            if (categoryModel?.Id > 0)
            {
                return new ApiResult("已经存在类目名称了");
            }
            var result = await WebHelper.DealTreeData(input.ParentId, input.Id, async () =>
              await _repository.GetModelAsync(d => d.Id == input.ParentId && !d.IsDeleted));
            categoryModel = _mapper.Map<Category>(input);
            categoryModel.ChangeParentList(result.Item1, result.Item2);
            var i = await _repository.UpdateAsync(categoryModel);
            return new ApiResult(i);
        }
        /// <summary>
        /// 所有父栏目
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetAllParentCategory()
        {
            var list = await _repository.GetListAsync(d => !d.IsDeleted && d.TenantId == _currentUserContex.TenantId);
            var data = new List<Category>();
            WebHelper.ChildNode(list, data, 0);
            if (data?.Count > 0)
            {
                foreach (var item in data)
                {
                    var name = WebHelper.LevelName(item.Name, item.Layer);
                    item.ChangeName(name);
                }
            }
            return new ApiResult(data);
        }

        /// <summary>
        /// 单个彻底删除
        /// </summary>
        /// <param name="deleteInput"></param>
        /// <returns></returns>
        [HttpDelete, Authority]
        public virtual async Task<ApiResult> Delete([FromBody] DeletesTenantInput deleteInput)
        {
            var res = await _repository.DeleteAsync(deleteInput.Ids);
            return res <= 0 ? new ApiResult("删除失败了！") : new ApiResult();
        }
        /// <summary>
        /// 软删除并将内容放回到回收站
        /// </summary>
        /// <param name="deleteInput"></param>
        /// <returns></returns>
        [HttpDelete, Authority(Action = nameof(BtnEnum.Recycle))] 
        public virtual Task<ApiResult> SoftDelete([FromBody] DeletesTenantInput deleteInput)
        {
            return _recycleRepository.SoftDeleteAsync(deleteInput, _repository);
        }
    }
}
